﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Server___console___class
{
    class Server
    {
        public TcpListener TcpListener;
        List<TcpClient> clients = new List<TcpClient>();
        private Form1 _form;
        private int _port;

        public Server(Form1 form, int port)
        {
            _form = form;
            _port = port;
        }

        public void ServerStart()
        {
            try
            {
                TcpListener = new TcpListener(IPAddress.Any, _port);
                _form.AsyncWriteLine("Server running");
            }
            catch (Exception ex)
            {
                _form.AsyncWriteLine("Server start error -> " + ex.Message);
            }
        }

        public void ListenForClients()
        {
            try
            {
                this.TcpListener.Start();
            }
            catch (Exception ex)
            {
                _form.AsyncWriteLine(ex.Message);
            }

            while (true)
            {
                    TcpClient client = this.TcpListener.AcceptTcpClient();
                    clients.Add(client);

                    _form.AsyncWriteLine(">> Client connected ");

                    foreach (TcpClient c in clients)
                    {
                        Thread clientThread = new Thread(new ParameterizedThreadStart(readFromStream));
                        clientThread.Start(c);
                    }
                
               
            }
        }

        private void readFromStream(object client)
        {
             TcpClient tcpClient = (TcpClient)client;
             NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            while (true)
            {
                bytesRead = 0;

                try
                {
                    bytesRead = clientStream.Read(message, 0, 4096);
                }
                catch
                {
                    _form.AsyncWriteLine(">> a socket error has occured!");
                    break;
                }

                if (bytesRead == 0)
                {
                    _form.AsyncWriteLine(">> the client has disconnected from the server!");
                    break;
                }

                ASCIIEncoding encoder = new ASCIIEncoding();
                _form.AsyncWriteLine("<< Data recieved: " + encoder.GetString(message, 0, bytesRead));



                byte[] buffer = encoder.GetBytes("Data recieved -> " + DateTime.Now.TimeOfDay);

                clientStream.Write(buffer, 0, buffer.Length);
                _form.AsyncWriteLine(">> Data sent: " + encoder.GetString(buffer, 0, buffer.Length));
                clientStream.Flush();

            }

            tcpClient.Close();


        }

        public void WriteToAllStreams(string message)
        {
            NetworkStream _clientStream;

            try
            {
                ASCIIEncoding _encoder = new ASCIIEncoding();
                byte[] buffer = _encoder.GetBytes(message);

                foreach (TcpClient c in clients)
                {
                    _clientStream = ((TcpClient)c).GetStream();
                    _clientStream.Write(buffer, 0, buffer.Length);
                    _clientStream.Flush();
                }
                
                _form.AsyncWriteLine(">> Data sent: " + message);
            }
            catch (Exception ex)
            {
                _form.AsyncWriteLine("Write to all streams error: " + ex.Message);
            }
        }

        public void ServerClose()
        {
            foreach (TcpClient c in clients)
            {
                c.Close();
            }
        }


    }
}
